/*------------------------------------------------------------------------------
 *
 * VDockSplitter.java - Implements a splitter component for a VDock
 * 
 * January 2009, Forhad Ahmed
 * 
 *------------------------------------------------------------------------------
 *
 *
 *------------------------------------------------------------------------------
 */

package ui.dock;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JComponent;

public class DockSplitter extends JComponent {
    public DockSplitter() {
        this.addMouseListener(new VDockSplitterMouseAdapter(this));
        this.addMouseMotionListener(new DockSplitterMouseMotionAdapter(this));

        objects++;
    }

    public void finalize() {

        objects--;
        System.out.print("VDockSplitter - ");
        System.out.println(objects);
    }
    
    public void drop() {
        src.syncAll();
        dst.syncAll();
    }
    
    public void drag(int x, int y, boolean continuous) {
        int h, v, oldX, oldY, dx = 0, dy = 0;
        int smw, smh, dmw, dmh;
        int capacity, off;

        assert (parent != null);
        assert (src != null);
        assert (dst != null);

        DockNode parent = (DockNode) this.parent;

        oldX = getX();
        oldY = getY();
        h = (int) (oldX - lastX + x);
        v = (int) (oldY - lastY + y);
        
        smw = src.minBoundaryLeafWidth(DockNode.DOCKNODE_RIGHT, 0xFFFF);
        smh = src.minBoundaryLeafHeight(DockNode.DOCKNODE_BOTTOM, 0xFFFF);
        dmw = dst.minBoundaryLeafWidth(DockNode.DOCKNODE_LEFT, 0xFFFF);
        dmh = dst.minBoundaryLeafHeight(DockNode.DOCKNODE_TOP, 0xFFFF);
        
        if (parent.orientation == Dock.DOCK_H) {
            h = oldX;
            dy = v - oldY;
            
            if (dy >= 0) {
                capacity = dmh - DockNode.DOCKNODE_MINSIZE;
                if (dy < capacity) {
                    off = 0;
                } else {
                    off = dy - capacity;
                    dy = capacity;
                }
            } else {
                capacity = smh - DockNode.DOCKNODE_MINSIZE;
                if (-dy < capacity) {
                    off = 0;
                } else {
                    off = dy + capacity;
                    dy = -capacity;
                }                    
            }
            
            if (capacity >= 0) {
                src.setBounds(src.x, src.y, src.w, src.h + dy);
                dst.setBounds(dst.x, dst.y + dy, dst.w, dst.h - dy);
                this.setLocation(h, v - off);
            }
        } else if (parent.orientation == Dock.DOCK_V) {
            v = oldY;
            dx = h - oldX;
            
            if (dx >= 0) {
                capacity = dmw - DockNode.DOCKNODE_MINSIZE;
                if (dx < capacity) {
                    off = 0;
                } else {
                    off = dx - capacity;
                    dx = capacity;   
                }
            } else {
                capacity = smw - DockNode.DOCKNODE_MINSIZE;
                if (-dx < capacity) {
                    off = 0;
                } else {
                    off = dx + capacity;
                    dx = -capacity;
                }
            }
            
            if (capacity >= 0) {
                src.setBounds(src.x, src.y, src.w + dx, src.h);
                dst.setBounds(dst.x + dx, dst.y, dst.w - dx, dst.h);
                this.setLocation(h - off, v);
            }
        }
        
        if (continuous) {
            src.syncAll();
            dst.syncAll();
        }
        
    }
    
    /*
     * Private data
     */
    protected DockNode src;
    protected DockNode dst;
    protected DockNode parent;
    protected int       lastX;
    protected int       lastY;
    
    /*
     * Options:
     * 
     * continuous: continuous or preview-based movement?
     * linear:     linear or boundary based resize of children?
     */
    protected boolean continuous = true;
    protected boolean linear     = false;
    
    
    public static int objects = 0;

}

class VDockSplitterMouseAdapter extends MouseAdapter {
    public VDockSplitterMouseAdapter(DockSplitter target) {
        this.target = target;
        objects++;
    }

    public void finalize() {
        objects--;
        System.out.print("VDockSplitterMouseAdapter - ");
        System.out.println(objects);
    }

    public void mouseEntered(MouseEvent e) {
        DockNode parent = target.parent;

        if (parent != null) {
            if (parent.orientation == Dock.DOCK_H) {
                /*
                 * TODO: set a vertical resize cursor
                 */
            } else if (parent.orientation == Dock.DOCK_V) {
                /*
                 * TODO; set a horizontal resize cursor
                 */
            }
        }
    }

    public void mousePressed(MouseEvent e) {
        target.lastX = e.getX();
        target.lastY = e.getY();

        System.out.println(target.src);
        System.out.println(target.dst);
        System.out.println(target.parent);
        System.out.println("");

    }

    public void mouseReleased(MouseEvent e) {
        if (target.continuous) {
            /*
             * NO-OP
             */
        } else {
            target.drop();
        }
    }

    protected DockSplitter target;
    public static int objects = 0;
}

class DockSplitterMouseMotionAdapter extends MouseMotionAdapter {
    public DockSplitterMouseMotionAdapter(DockSplitter target) {
        this.target = target;
        objects++;
    }

    public void finalize() {
        objects--;
        System.out.print("VDockSplitterMouseMotionAdapter - ");
        System.out.println(objects);
    }

    public void mouseDragged(MouseEvent e) {
        target.drag(e.getX(), e.getY(), target.continuous);
    }

    protected DockSplitter target;
    public static int objects = 0;
}